﻿using System.Data;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using MvcApplication2.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Mvc;
using AutoMapper;
using MvcApplication2.Models;

/*
 *  - Per entrare in quest'area l'utente deve essere autenticato.
 */
namespace MvcApplication2.Controllers
{
    [Authorize]
    public class DeveloperController : ControllerEx
    {
        private MvcApplication2Context db = new MvcApplication2Context();

        public DeveloperController()
        {
            ViewBag.Devices = db.Devices.ToList();

        }

        //public ActionResult AskDifferentPrice(int id = 0)
        //{
        //    var user = ModelHelper.GetUser(db);

        //    var viewModel = UserMessageHelper.GetProposal(id, db, false);

        //    if (viewModel == null) return RedirectToAction("MyExercises");

        //    return View("SendProposal", viewModel);
        //}

        //[HttpPost]
        //public ActionResult AskDifferentPrice(UserMessageViewModel proposal, FormCollection formCollection)
        //{
        //    var success = UserMessageHelper.CreateChildProposal(db, proposal.UserMessageId, proposal.Reward, proposal.Message,
        //                                                                "tester");
        //    if (success)
        //    {
        //        return RedirectToAction("MyExercises");
        //    }

        //    // todo: inserire messaggi di errore
        //    return RedirectToAction("SendProposal", proposal.UserMessageId);
        //}

        /// <summary>
        /// Dev side.
        /// Mando proposta a utente,
        /// Creo message vuoto solamente con testerid e exerciseid in modo da identificarlo successivamente
        /// </summary>
        [Authorize]
        public ActionResult SendProposal(int exerciseId = 0, int testerId = 0)
        {
            var exmessage = UserMessageHelper.TesterExerciseGet(db, exerciseId, testerId);

            var vm = ModelHelper.CopyTo<UserMessage, UserMessageViewModel>(exmessage);

            return View(vm);
        }

        /// <summary>
        /// Qui verrà creato il messaggio di proposta
        /// </summary>
        [HttpPost]
        [Authorize]
        public ActionResult SendProposal(UserMessageViewModel mess)
        {
            var success = UserMessageHelper.TesterExercisePost(db, mess.ExerciseId, mess.TesterId, mess.Reward, mess.Message, "dev");

            if (success)
            {
                AddSuccessMessage("Proposta Inviata !");
            }
            else
            {
                AddErrorMessage("Errore invio proposta !");

            }
            return RedirectToAction("FindTesters", new RouteValueDictionary() { { "id", mess.ExerciseId } });
        }

        /*
         * Una volta accettato esercizio, posso creare cancellare tutti o forse e meglio di no.
         * cosi riesco a tenere salvati i messaggi.
         * setto inattivo e setto completato il seguente.
         * cosi posso tenere traccia anche degli altri cambi di stato e messaggi sempre inerenti all'esercizio
         */
        public ActionResult AcceptTestExercise(int id = 0)
        {
            var test = db.UserMessages.Find(id);

            test.ExerciseStatus = ExerciseStatusType.WaitingTest;

            db.SaveChanges();


            return RedirectToAction("MyExercises");
        }

        public ActionResult CreateExercises()
        {
            ViewBag.Title = "Create";
            return View("SingleExercise");
        }

        [HttpPost]
        public ActionResult CreateExercises(Exercise exercise, FormCollection formCollection)
        {
            ViewBag.Title = "Create";
            var save = formCollection["save"];
            var publish = formCollection["publish"];

            var u = ModelHelper.GetUser(db);

            exercise.Owner = u;
            exercise.OwnerId = u.UserProfileId;
            exercise.Status = "draft";

            if (exercise.ExerciseId == 0)
            {
                db.Exercises.Add(exercise);
                db.SaveChanges();
            }
            else
            {
                exercise = db.Exercises.Find(exercise.ExerciseId);
                TryUpdateModel(exercise, formCollection);
            }

            if (publish != null)
            {
                exercise.Status = "published";
                //db.SaveChanges();
                //return RedirectToAction("Index");
            }

            db.SaveChanges();
            return RedirectToAction("Exercises");

            //return RedirectToAction("Edit", new RouteValueDictionary(){{"id",exercise.ExerciseId}});
        }

        public ActionResult ExerciseDetails(int id = 0)
        {
            var ex = db.Exercises.Find(id);

            return View(ex);
        }

        public ActionResult EditExercise(int id = 0)
        {
            ViewBag.Title = "Edit";

            Exercise exercise = db.Exercises.Find(id);
            if (exercise == null)
            {
                return HttpNotFound();
            }
            return View("SingleExercise", exercise);
        }


        [HttpPost]
        public ActionResult EditExercise(Exercise exercise, FormCollection formCollection)
        {
            ViewBag.Title = "Edit";
            var save = formCollection["save"];
            var publish = formCollection["publish"];

            if (ModelState.IsValid)
            {
                if (publish != null)
                    exercise.Status = "published";

                db.Entry(exercise).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Exercises");
            }


            return View("SingleExercise", exercise);
        }

        //
        // GET: /DeveloperExercise/Delete/5

        public ActionResult DeleteExercise(int id = 0)
        {
            Exercise exercise = db.Exercises.Find(id);
            if (exercise == null)
            {
                return HttpNotFound();
            }
            return View("ExerciseDelete", exercise);
        }

        //
        // POST: /DeveloperExercise/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteExerciseConfirmed(int id)
        {
            //Exercise exercise = db.Exercises.Find(id);

            //var p2 = exercise.UserMessages;

            var exercise1 = db.Exercises.Include(t => t.ThreadMessages).First(p => p.ExerciseId == id);

            //var p1 = exercise.UserMessages;
            db.Exercises.Remove(exercise1);
            db.SaveChanges();
            return RedirectToAction("Exercises");
        }
        public ActionResult Exercises()
        {
            var u = ModelHelper.GetUser(db);

            return View(u.Exercises.ToList());
        }


        /// <summary>
        /// Mostra la lista dei tester compatibili con l'esercizio corrente
        /// . fare paging .
        /// </summary>
        public ActionResult FindTesters(int id = 0)
        {
            ViewBag.exerciseId = id;

            var currentUser = ModelHelper.GetUser(db);

            // fare inclusione utente
            var exercise = db.Exercises.Find(id);

            if (exercise == null) return View();

            var dev = exercise.Owner;

            if (dev.UserProfileId != currentUser.UserProfileId) throw new Exception("UserNotAllowed");

            //var testers =
            //   db.UsersProfiles.Where(
            //       k => k.Languages.Intersect(user.Languages).Any() && k.Devices.Contains(exercise.Device)).ToList();

            IEnumerable<UserProfile> testers = new List<UserProfile>();
            foreach (var language in dev.Languages)
            {
                var language1 = language;
                var temp =
                    db.UsersProfiles.Where(u => u.AcceptTestingRequest && u.Devices.Any(p => p.DeviceId == exercise.Device.DeviceId) && u.Languages.Any(l => l.LanguageId == language1.LanguageId));

                testers = testers.Union(temp);
            }
            //var testers = (from u in db.UsersProfiles.Include(us => us.Languages).Include(us => us.Devices)
            //               from t in db.UsersProfiles.Where(de => de.UserProfileId == dev.UserProfileId)
            //               from e in db.Exercises.Where(de => de.ExerciseId == exercise.ExerciseId)
            //               where u.AcceptTestingRequest
            //               from d in u.Devices
            //               from lan in u.Languages
            //               from lanOwner in t.Languages
            //               where d.DeviceId == e.DeviceId
            //               where lan.LanguageId == lanOwner.LanguageId
            //               select u).ToList();

            var vm = new FindTesterViewModel();

            // In base al device setto prorietà.
            vm.ExerciseTitle = exercise.Title;
            vm.CanScreenCapture = true;
            vm.CanWebcamRecording = true;

            foreach (var language in dev.Languages)
            {
                vm.LanguagesFiltered += language.Description;
            }

            foreach (var userProfile in testers)
            {
                var testerVm = ModelHelper.CopyTo<UserProfile, UserProfileFindTesterViewModel>(userProfile);

                var alredySended =
                    (db.UserMessages.Include(m => m.UsersAllowed).Where(
                        m =>
                        m.ExerciseId == exercise.ExerciseId &&
                        m.Type == UserMessageType.TesterExercise &&
                        m.UsersAllowed.Any(o => o.UserProfileId == userProfile.UserProfileId))).Any();

                var message = "No proposte in corso";

                if (alredySended)
                    message = "Proposta già spedita !";

                testerVm.ProposalSendedMessage = message;

                vm.Testers.Add(testerVm);
            }

            if (exercise.Device != null) vm.TargetDevice = exercise.Device.Description;

            return View(vm);
        }

        ///// <summary>
        ///// Lista di esercizi tester
        ///// </summary>
        ///// <param name="filter"></param>
        ///// <returns></returns>
        //[Authorize]
        //public ActionResult MyExercises(string filter)
        //{
        //    var user = ModelHelper.GetUser(db);

        //    var vms1 = UserMessageHelper.GetExercises(db, user.UserProfileId, false);

        //    //var workMsg =
        //    //    db.UserMessages.Include(t => t.Exercise).Include(t => t.ParentMessage).Where(m => m.Type == ThreadMessageType.TesterExercise && m.ExerciseStatus == ExerciseStatusType.ProposalActive).Where(
        //    //        m1=> m1.ParentMessage.UsersAllowed.Any(m2 => m2.UserId == user.UserId)).ToList();

        //    ////var workMsg =
        //    ////    db.UserMessages.Include(l=>l.).Where(m => m.Type == (byte)ThreadMessageType.TesterExercise).Where(
        //    ////        m1 => m1.Owner.UserId == user.UserId || m1.UsersAllowed.Any(m2 => m2.UserId == user.UserId)).ToList();

        //    //var vms = ModelHelper.GetListViewModel<UserMessage, ExerciseTestViewModel>(workMsg);

        //    //foreach (var vm in vms)
        //    //{
        //    //    vm.IsTesterSide = false;
        //    //}

        //    return View(vms1);
        //}

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }


    }
}